package com.example.book.interceptor;

import java.io.PrintWriter;

import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.example.book.annotation.IgnoreAuth;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.example.book.entity.TokenEntity;
import com.example.book.service.TokenService;
import com.example.book.utils.R;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

/**
 * 权限(Token)验证,自定义拦截器
 */
@Slf4j
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {
    public static final String LOGIN_TOKEN_KEY = "token";

    @Autowired
    private TokenService tokenService;
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("自定义拦截器，preHandle");
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        //支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            //检查该请求是否为Controller方法，若是通过强制类型转换将 handler 转换为 HandlerMethod 对象，
            //并使用 getMethodAnnotation 方法来获取该方法上的注解信息。
            //如果该方法上存在 IgnoreAuth 注解，则 annotation 将被赋值为该注解对象，表示该请求不需要认证。
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            //如果 handler 不是 HandlerMethod 的实例，可能表示这不是一个 Controller 方法的请求，那么代码就直接返回 true
            return true;
        }
        //不需要验证权限的方法直接放过
        if(annotation!=null) {
            return true;
        }
        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        TokenEntity tokenEntity = null;
        if(StringUtils.isNotBlank(token)) {
            tokenEntity = tokenService.getTokenEntity(token);
        }

        if(tokenEntity != null) {
            request.getSession().setAttribute("userId", tokenEntity.getUserid());
            request.getSession().setAttribute("role", tokenEntity.getRole());
            request.getSession().setAttribute("tableName", tokenEntity.getTablename());
            request.getSession().setAttribute("username", tokenEntity.getUsername());
            return true;
        }

        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
        } finally {
            if(writer != null){
                writer.close();
            }
        }
        return false;
    }
}
